Enemy Behaviors
Each enemy was built on a shared AIBehavior base class, with individual types overriding and extending behavior through coroutine-driven logic.
This structure kept shared systems — detection, damage, freezing — centralized, while allowing each enemy to define its own movement patterns, attack routines, and range thresholds independently.
Detection & Line of Sight
Enemies use distance checks and raycasts against player and environment layer masks to determine when to engage. Rather than polling continuously, detection feeds directly into coroutine entry points — once a threshold is crossed, the appropriate behavior routine is launched and locked until it completes. This prevents state conflicts and keeps each enemy's decision loop clean and predictable.
Patrol & Idle Roaming
Enemies in a non-engaged state use NavMesh-driven patrol routes to move through the environment. Waypoint selection and dwell timers are exposed as serialized fields, allowing the designer to tune patrol feel per enemy type without touching code.
Ranged vs. Melee Logic
Each enemy has configurable range thresholds that determine which attack mode activates. A boolean rangeFlip field — added directly in response to designer feedback — inverts the range priority, letting the same enemy script support both "aggressive at close range" and "aggressive at distance" archetypes without duplicating logic.